package com.dms.common.config;

import com.dms.common.security.JwtAuthenticationFilter;
import com.dms.common.security.JwtAuthenticationEntryPoint;
import com.dms.common.security.JwtTokenProvider;
import com.dms.modules.merchant.service.impl.MerchantUserDetailsService;
import com.dms.modules.user.service.impl.UserServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.util.Arrays;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final JwtAuthenticationEntryPoint unauthorizedHandler;
    private final JwtTokenProvider jwtTokenProvider;
    private final UserServiceImpl userService;
    private final MerchantUserDetailsService merchantUserDetailsService;

    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() {
        return new JwtAuthenticationFilter(jwtTokenProvider);
    }

    @Bean
    public static PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(10);
    }

    @Bean
    public AuthenticationManager authenticationManager() {
        return new ProviderManager(Arrays.asList(
            userAuthenticationProvider(),
            merchantAuthenticationProvider()
        ));
    }

    @Bean
    public AuthenticationProvider userAuthenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userService);
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }

    @Bean
    public AuthenticationProvider merchantAuthenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(merchantUserDetailsService);
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .cors().and().csrf().disable()
            .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
            .authorizeHttpRequests()
            // 认证相关公开接口
            .antMatchers("/api/v1/user/auth/login", "/api/v1/user/auth/register", "/api/v1/user/auth/verify-code",
                "/api/v1/admin/auth/login", "/api/v1/merchant/auth/login").permitAll()
                
            // Swagger文档相关公开接口
            .antMatchers("/swagger-ui/**", "/v3/api-docs/**", "/swagger-resources/**", "/webjars/**").permitAll()
            
            // 商品相关公开接口
            .antMatchers(
                "/api/v1/products",
                "/api/v1/products/**",
                "/api/v1/products/categories/**",
                "/api/v1/products/search",
                "/api/v1/products/recommend"
            ).permitAll()
            
            // 地区相关公开接口
            .antMatchers("/api/v1/region/**").permitAll()
            
            // 支付宝回调接口不需要认证
            .antMatchers("/api/v1/payment/alipay/notify", "/api/v1/payment/alipay/return").permitAll()
            
            // 角色限制
            .antMatchers("/api/v1/merchant/**").hasRole("MERCHANT")
            .antMatchers("/api/v1/admin/**").hasRole("ADMIN")
            .antMatchers("/api/v1/system/**").hasRole("ADMIN")
            
            // 其他接口需要认证
            .anyRequest().authenticated();

        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }
} 